package com.xmb.wpclient.service.impl;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xmb.wpclient.cache.CommonCache;
import com.xmb.wpclient.entity.BaseCommonConstant;
import com.xmb.wpclient.entity.BaseCommonDataDictionaryAndSet;
import com.xmb.wpclient.entity.BaseCommonQueryTable;
import com.xmb.wpclient.mapper.BaseCommonDataDictionaryAndSetMapper;
import com.xmb.wpclient.service.IBaseCommonConstantService;
import com.xmb.wpclient.service.IBaseCommonDataDictionaryAndSetService;
import com.xmb.wpclient.service.IBaseCommonQueryTableService;
import com.xmb.wpclient.utils.LockUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author huangping
 * @since 2023-03-22
 */
@Service
public class BaseCommonDataDictionaryAndSetServiceImpl extends ServiceImpl<BaseCommonDataDictionaryAndSetMapper, BaseCommonDataDictionaryAndSet> implements IBaseCommonDataDictionaryAndSetService {

    @Autowired
    private BaseCommonDataDictionaryAndSetMapper commonDataDictionaryAndSetMapper;

    @Autowired
    private IBaseCommonConstantService iBaseCommonConstantService;

    @Autowired
    private IBaseCommonQueryTableService iBaseCommonQueryTableService;

    @Autowired
    @Lazy
    private CommonCache commonCache;

    @Override
    public List<BaseCommonDataDictionaryAndSet> getTableInfo(Long id) {
        synchronized (LockUtils.getLock("tableConstantId:"+ id)) {
            BaseCommonConstant constant = iBaseCommonConstantService.getById(id);
            List<BaseCommonDataDictionaryAndSet> list = list(new LambdaQueryWrapper<BaseCommonDataDictionaryAndSet>().eq(BaseCommonDataDictionaryAndSet::getConstantId, id));
            if(list.size() > 0){
                return list;
            }
            List<BaseCommonDataDictionaryAndSet> infoList = commonDataDictionaryAndSetMapper.getTableInfo(constant.getUrl());
            for(BaseCommonDataDictionaryAndSet commonDataDictionaryAndSet : infoList){
                commonDataDictionaryAndSet.setConstantId(id);
                commonDataDictionaryAndSet.setConstantUrl(constant.getUrl());
                commonDataDictionaryAndSet.setEntityField(StrUtil.toCamelCase(commonDataDictionaryAndSet.getTableField()));
                commonDataDictionaryAndSet.setDefaultShow(commonDataDictionaryAndSet.getTableField().equals("id")?false:true);
                commonDataDictionaryAndSet.setDefaultValue(commonDataDictionaryAndSet.getTableField().equals("id")?"Auto":commonDataDictionaryAndSet.getTableField().equals("create_user")?"user":commonDataDictionaryAndSet.getTableField().equals("create_time")?"date":null);
                commonDataDictionaryAndSet.setQueryCriteria(false);
                commonDataDictionaryAndSet.setUniqueness(commonDataDictionaryAndSet.getTableField().equals("code")?true:false);
                commonDataDictionaryAndSet.setDisable(commonDataDictionaryAndSet.getTableField().equals("disable")?true:false);
                commonDataDictionaryAndSet.setRequired(false);
            }
            saveBatch(infoList);
            return infoList;
        }
    }

    @Override
    @Transactional
    public List<BaseCommonDataDictionaryAndSet> refreshTableInfo(Long id) {
        BaseCommonConstant constant = iBaseCommonConstantService.getById(id);
        List<BaseCommonDataDictionaryAndSet> list = list(new LambdaQueryWrapper<BaseCommonDataDictionaryAndSet>().eq(BaseCommonDataDictionaryAndSet::getConstantId, id));
        List<BaseCommonDataDictionaryAndSet> infoList = commonDataDictionaryAndSetMapper.getTableInfo(constant.getUrl());
        Iterator<BaseCommonDataDictionaryAndSet> iterator = list.iterator();
        while (iterator.hasNext()){
            BaseCommonDataDictionaryAndSet next = iterator.next();
            boolean flag = true;
            for(BaseCommonDataDictionaryAndSet commonDataDictionaryAndSet : infoList){
                if(commonDataDictionaryAndSet.getTableField().equals(next.getTableField())){
                    flag = false;
                }
            }
            if(flag){
                List<BaseCommonQueryTable> queryTableList = iBaseCommonQueryTableService.list(new LambdaQueryWrapper<BaseCommonQueryTable>().eq(BaseCommonQueryTable::getDictionaryId, next.getId()));
                if(queryTableList.size() > 0){
                    iBaseCommonQueryTableService.removeBatchByIds(queryTableList);
                }
                removeById(next);
                iterator.remove();
            }
        }
        for(BaseCommonDataDictionaryAndSet commonDataDictionaryAndSet : infoList){
            boolean flag = true;
            for(BaseCommonDataDictionaryAndSet dataDictionaryAndSet : list){
                if(commonDataDictionaryAndSet.getTableField().equals(dataDictionaryAndSet.getTableField())){
                    flag = false;
                }
            }
            if(flag){
                commonDataDictionaryAndSet.setConstantId(id);
                commonDataDictionaryAndSet.setConstantUrl(constant.getUrl());
                commonDataDictionaryAndSet.setEntityField(StrUtil.toCamelCase(commonDataDictionaryAndSet.getTableField()));
                commonDataDictionaryAndSet.setDefaultShow(commonDataDictionaryAndSet.getTableField().equals("id")?false:true);
                commonDataDictionaryAndSet.setDefaultValue(commonDataDictionaryAndSet.getTableField().equals("id")?"Auto":commonDataDictionaryAndSet.getTableField().equals("create_user")?"user":commonDataDictionaryAndSet.getTableField().equals("create_time")?"date":null);
                commonDataDictionaryAndSet.setQueryCriteria(false);
                commonDataDictionaryAndSet.setUniqueness(commonDataDictionaryAndSet.getTableField().equals("code")?true:false);
                commonDataDictionaryAndSet.setDisable(commonDataDictionaryAndSet.getTableField().equals("disable")?true:false);
                commonDataDictionaryAndSet.setRequired(false);
                list.add(commonDataDictionaryAndSet);
                save(commonDataDictionaryAndSet);
            }
        }
        commonCache.removeByUrl(constant.getUrl());
        return list;
    }

    @Override
    @Transactional
    public void saveQueryTable(Long id, Long constantId, String associatedFiled, String fields) throws Exception {
        BaseCommonDataDictionaryAndSet dictionaryAndSet = getById(id);
        if(dictionaryAndSet == null){
            throw new Exception();
        }
        dictionaryAndSet.setQueryConstantId(constantId);
        dictionaryAndSet.setAssociatedFiled(associatedFiled);
        List<String> fieldList = JSON.parseArray(fields, String.class);
        if(fieldList.size() < 1){
            throw new Exception();
        }
        updateById(dictionaryAndSet);
        List<BaseCommonQueryTable> queryList = new ArrayList<>();
        for(String field : fieldList){
            BaseCommonQueryTable commonQueryTable = new BaseCommonQueryTable();
            commonQueryTable.setDictionaryId(id);
            commonQueryTable.setQueryField(field);
            queryList.add(commonQueryTable);
        }
        long count = iBaseCommonQueryTableService.count(new LambdaQueryWrapper<BaseCommonQueryTable>().eq(BaseCommonQueryTable::getDictionaryId, id));
        if(count > 0){
            iBaseCommonQueryTableService.remove(new LambdaQueryWrapper<BaseCommonQueryTable>().eq(BaseCommonQueryTable::getDictionaryId, id));
        }
        iBaseCommonQueryTableService.saveBatch(queryList);
        commonCache.removeByUrl(dictionaryAndSet.getConstantUrl());
    }
}
